﻿using Geek.Server.Core.Serialize;
using Geek.Server.Core.Storage;
using Geek.Server.DemoClient.Core;
using MongoDB.Bson.IO;
using PolymorphicMessagePack;

namespace Geek.Server.DemoClient
{
    public abstract class Program
    {
        public static async Task Main(string[] args)
        {
            BsonClassMapHelper.SetConvention();
            BsonClassMapHelper.RegisterAllClass(typeof(CommonResp).Assembly);
            BsonClassMapHelper.RegisterAllClass(typeof(Program).Assembly);
            
            PolymorphicTypeMapper.Register(typeof(CommonResp).Assembly);
            MsgFactory.Init(typeof(CommonResp).Assembly);
            PolymorphicResolver.Instance.Init();
            LogManager.Configuration = new XmlLoggingConfiguration("Configs/test_log.config");
            JsonWriterSettings.Defaults = new JsonWriterSettings
            {
                Indent = false,
                OutputMode = JsonOutputMode.RelaxedExtendedJson
            };

            TestSettings.Load("Configs/test_config.json");

            await AddServer();
            await QueryServerList();
            await UpdateServer();
            await QueryServerList();
            await Login(LoginSDKType.Guest, "DemoClient", "DemoClient", "DemoClient", CancellationToken.None);
        }

        private static async Task QueryServerList()
        {
            var logger = LogManager.GetCurrentClassLogger();
            
            var resp = await new WebQueryServerListReq
            {
                DeviceId = "DemoClient",
            }.Execute();
            
            logger.Info(resp.ToJsonStr());
        }

        private static async Task UpdateServer()
        {
            var logger = LogManager.GetCurrentClassLogger();
            
            var serverInfo = new ServerInfo
            {
                Id = 1001,
                Flags = ServerFlags.New,
                OpenTime = new DateTime(2024, 1, 1, 0, 0, 0),
                Ip = "127.0.0.1",
                Port = 8899
            };
            
            var resp = await HttpUtils.SendAsync(new WebUpdateServerInfoReq
            {
                ServerInfo = serverInfo
            }, CancellationToken.None);
            
            logger.Info(resp.ToJsonStr());
        }

        private static async Task AddServer()
        {
            var logger = LogManager.GetCurrentClassLogger();
            
            var serverInfo = new ServerInfo
            {
                Id = 1001,
                Flags = ServerFlags.New | ServerFlags.Recommend,
                OpenTime = new DateTime(2024, 1, 1, 0, 0, 0),
                Ip = "127.0.0.1",
                Port = 8899
            };
            
            var resp = await HttpUtils.SendAsync(new WebAddServerInfoReq
            {
                ServerInfo = serverInfo
            }, CancellationToken.None);
            
            logger.Info(resp.ToJsonStr());
        }

        private static async Task Login(LoginSDKType sdkType, string sdkUid, string sdkToken, string deviceId, CancellationToken token)
        {
            var logger = LogManager.GetCurrentClassLogger();

            var authResp = await new WebAuthReq
            {
                SDKType = sdkType,
                SDKUid = sdkUid,
                SDKToken = sdkToken,
                DeviceId = deviceId,
            }.Execute(token);

            logger.Info(authResp.ToJsonStr());

            if (token.IsCancellationRequested)
                return;

            var resp = await new WebQueryServerListReq
            {
                DeviceId = "DemoClient",
                AccountId = authResp.AccountId,
            }.Execute(token);
            
            logger.Info(resp.ToJsonStr());

            var client = new Client();
            var success = await client.ConnectAsync();

            if (!success)
            {
                logger.Error("连接服务器失败");
                return;
            }

            if (token.IsCancellationRequested)
                return;

            var loginResp = await client.SendRequestAsync<LoginResp>(new LoginReq
            {
                DeviceId = deviceId,
                Platform = GamePlatform.Windows,
                AccountId = authResp.AccountId,
                LoginToken = authResp.LoginToken
            });

            logger.Info(loginResp.ToJsonStr());

            if (token.IsCancellationRequested)
                return;

            var queryResponse = await new WebQueryAccountRoleReq
            {
                AccountId = authResp.AccountId,
                ServerId = 1001
            }.Execute(token);
            
            logger.Info(queryResponse.ToJsonStr);
        }
    }
}